#ifndef __CPODATA_H__
#define __CPODATA_H__

#include <stdio.h>
#include <pthread.h>
#include <stdbool.h>
#include <assert.h>
#include <signal.h>
#include "datacpy.h"
#include "list.h"

#define APPNAME "CPO"

/* 点位name tag<-->点位name */
/* 虚点 */
#define TEMP_ERR        "TEMP-ERR"      // double 温度偏差
#define CH_RT           "CH-RT"         // unsigned int 冷机运行时间
#define CH_REAL_IP      "CH-REAL-IP"    // double 即时输入功率（电）
#define CH_MAX_OP       "CH-MAX-OP"     // double 最大输出功率（制冷）
#define E_DP_MIN        "E-DP-MIN"      // double 最不利末端压差设定值
#define CH_NUM          "CH-NUM"        // unsigned int 冷机当前运行台数
#define PCHWP_NUM       "PCHWP-NUM"     // unsigned int 初级冷冻水泵运行台数
#define CWP_NUM         "CWP-NUM"       // unsigned int 冷却水泵运行台数
#define CTF_NUM         "CTF-NUM"       // unsigned int 冷却塔风机运行台数
#define CHW_BP_DPSP     "CHW-BP-DPSP"   // double 冷冻水旁通阀压差设定点
#define CTS_TSP         "CTS-TSP"       // double 冷却塔出水温度设定
#define C_CALL          "C-CALL"        // bool 系统总启停命令
#define CHW_TSP_V       "CHW-TSP-V"     // double 冷机出水温度设定值
#define C_LOAD          "C-LOAD"        // double 系统冷负荷，必选点位，初始值0, 程序赋值，定时向平台反应
#define CH_MIN_CT       "CH-MIN-CT"     // unsigned int 冷机关机最小时间间隔
#define CH_MIN_OT       "CH-MIN-OT"     // unsigned int 冷机开机最小时间间隔
#define CH_AD_RT        "CH-AD-RT"      // unsigned int 冷机软启动提前开始时间
#define CH_MAX_RT       "CH-MAX-RT"     // unsigned int 冷机最长连续运行时间
#define CH_MIN_RT       "CH-MIN-RT"     // unsigned int 冷机关机前最小运行时间
#define CH_MIN_DT       "CH-MIN-DT"     // unsigned int 冷机启动前最小停机时间
#define CH_MIN_RESTT    "CH-MIN-RESTT"  // unsigned int 冷机轮休时最短休息时间
#define CH_MAX_WT       "CH-MAX-WT"     // unsigned int 冷机冷冻水温度设定值上限
#define CH_MIN_WT       "CH-MIN-WT"     // unsigned int 冷机冷冻水温度设定值下限
#define CH_MIN_LOAD     "CH-MIN-LOAD"   // unsigned int 冷机最小运行负载
#define PUMP_MAX_RT     "PUMP-MAX-RT"   // unsigned int 水泵最长连续运行时间
#define PUMP_MIN_RT     "PUMP-MIN-RT"   // unsigned int 水泵关机前最小运行时间
#define PUMP_MIN_DT     "PUMP-MIN-DT"   // unsigned int 水泵启动前最小停机时间
#define PUMP_MIN_RESTT  "PUMP-MIN-RESTT"    // unsigned int 水泵轮休时最短休息时间
#define CTF_MAX_RT      "CTF-MAX-RT"    // unsigned int 冷却塔风机最长连续运行时间
#define CTF_MIN_RT      "CTF-MIN-RT"    // unsigned int 冷却塔风机关机前最小运行时间
#define CTF_MIN_DT      "CTF-MIN-DT"    // unsigned int 冷却塔风机启动前最小停机时间
#define CTF_MIN_RESTT   "CTF-MIN-RESTT" // unsigned int 冷却塔风机轮休时最短休息时间

#define PCHWP_IS_VSD    "PCHWP-IS-VSD"  // bool true: 变频，false：定频，此点位不能为空，由平台给值
#define PCHWP_VSD_MAX   "PCHWP-VSD-MAX" // double 初级冷冻水泵频率上限，如果变频，那么此点位不能为空
#define PCHWP_VSD_MIN   "PCHWP-VSD-MIN" // double 初级冷冻水泵频率下限，如果变频，那么此点位不能为空
#define CWP_IS_VSD      "CWP-IS-VSD"    // 
#define CWP_VSD_MAX     "CWP-VSD-MAX"   // 
#define CWP_VSD_MIN     "CWP-VSD-MIN"   // 
#define CTF_IS_VSD      "CTF-IS-VSD"    // 
#define CTF_VSD_MAX     "CTF-VSD-MAX"   // 
#define CTF_VSD_MIN     "CTF-VSD-MIN"   // 

#define PCHWP           "PCHWP"         // 初级冷冻水泵
#define CWP             "CWP"           // 冷却水泵

#define CTG             "CTG"           // 冷却塔组
#define CT              "CT"            // 冷却塔
#define CTF             "CTF"           // 冷却塔风扇
#define CT_SYS          "CT-SYS"        // 单个塔的总点位, 也包括一组风扇的总点位
#define CTG_SYS         "CTG-SYS"       // 冷却塔组的总点位

#define CHG             "CHG"           // 冷机组
#define CH              "CH"            // 冷机
#define CHG_SYS         "CHG-SYS"       // 冷机组的总点位

#define CTF_IS_PBV      "CTF-IS-PBV"    // 是否共用蝶阀

/* 实点 */
#define CH_C            "CH-C"          // bool 冷机启停开关
#define CH_S            "CH-S"          // bool 冷机运行状态
#define CH_F            "CH-F"          // bool 冷机故障状态
#define CH_AM           "CH-AM"         // bool 冷机手自动
#define CHIV_VC         "CHIV-VC"       // bool 冷机冷冻水侧蝶阀开关
#define CHIV_OS         "CHIV-OS"       // bool 冷机冷冻水侧蝶阀开状态反馈
#define CHIV_CS         "CHIV-CS"       // bool 冷机冷冻水侧蝶阀关状态反馈
#define CHIV_S          "CHIV-S"        // bool 冷机冷冻水侧蝶阀开关状态反馈
#define CWIV_VC         "CWIV-VC"       // bool 冷机冷却水侧蝶阀开关控制
#define CWIV_OS         "CWIV-OS"       // bool 冷机冷却水侧蝶阀开状态反馈
#define CWIV_CS         "CWIV-CS"       // bool 冷机冷却水侧蝶阀关状态反馈
#define CWIV_VS         "CWIV-VS"       // bool 冷机冷却水侧蝶阀开关状态反馈
#define CHW_FLS         "CHW-FLS"       // bool 冷机冷冻水水流状态
#define CW_FLS          "CW-FLS"        // bool 冷机冷却水水流状态
#define CH_LOAD         "CH-LOAD"       // double 冷机属性冷水机运行负荷
#define CHW_TSP         "CHW-TSP"       // double 冷机出水温度设定点
#define PCHWP_C         "PCHWP-C"       // bool 初级冷冻水泵启停开关
#define PCHWP_S         "PCHWP-S"       // bool 初级冷冻水泵运行状态
#define PCHWP_F         "PCHWP-F"       // bool 初级冷冻水泵故障状态
#define PCHWP_AM        "PCHWP-AM"      // bool 初级冷冻水泵手/自动状态
#define PCHWP_FLOW      "PCHWP-FLOW"    // double 初级冷冻水泵额定流量
#define PCHWP_VSD       "PCHWP-VSD"     // double 初级冷冻水泵频率调节
#define PCHWP_VSD_FB    "PCHWP-VSD-FB"      // double 初级冷冻水泵频率反馈
#define PCHWP_VSD_C     "PCHWP-VSD-C"           // bool 初级冷冻水泵变频器启停
#define CWP_C           "CWP-C"         // bool 冷却水泵启停开关
#define CWP_VSD         "CWP-VSD"       // double 冷却水泵频率调节
#define CWP_VSD_FB      "CWP-VSD-FB"    // double 冷却水泵频率反馈
#define CWP_VSD_C       "CWP-VSD-C"     // bool 冷却水泵变频器启停
#define CWP_S           "CWP-S"         // bool 冷却水泵运行状态
#define CWP_F           "CWP-F"         // bool 冷却水泵故障状态
#define CWP_AM          "CWP-AM"        // bool 冷却水泵手/自动状态
#define CWP_FLOW        "CWP-FLOW"      // double 冷却水泵额定流量
#define CTF_C           "CTF-C"         // bool 冷却塔风扇启停开关
#define CTF_S           "CTF-S"         // bool 冷却塔风扇状态
#define CTF_F           "CTF-F"         // bool 冷却塔风扇故障报警
#define CTF_AM          "CTF-AM"        // bool 冷却塔风扇手自动
#define CTF_VSD         "CTF-VSD"       // double 冷却塔风机变频调节
#define CTF_VSD_C       "CTF-VSD-C"     // bool 冷却塔风机变频器启停
#define CTF_VSD_FB      "CTF-VSD-FB"    // double 冷却塔风机频率反馈
#define CTSV_OS         "CTSV-OS"       // bool 冷却塔供水蝶阀开状态反馈
#define CTSV_CS         "CTSV-CS"       // bool 冷却塔供水蝶阀关状态反馈
#define CTRV_OS         "CTRV-OS"       // bool 冷却塔回水蝶阀开状态反馈
#define CTRV_CS         "CTRV-CS"       // bool 冷却塔回水蝶阀关状态反馈
#define CTSV_S          "CTSV-S"        // bool 冷却塔供水蝶阀开关状态
#define CTRV_S          "CTRV-S"        // bool 冷却塔回水蝶阀开关状态
#define CTSV_C          "CTSV-C"        // bool 冷却塔供水蝶阀开关命令
#define CTRV_C          "CTRV-C"        // bool 冷却塔回水蝶阀开关命令
#define CHBPV_FB        "CHBPV-FB"      // double 冷冻水旁通阀反馈
#define CHBPV_C         "CHBPV-C"       // double 冷冻水旁通阀调节命令
#define CCHWS_T         "CCHWS-T"       // double 冷冻水总管出水温度
#define CCHWR_T         "CCHWR-T"       // double 冷冻水总管回水温度
#define CCHWS_P         "CCHWS-P"       // double 冷冻水总管供水压力
#define CCHWR_P         "CCHWR-P"       // double 冷冻水总管回水压力
#define CHW_DP          "CHW-DP"        // double 冷冻水总管供回水压差
#define CCHW_FL         "CCHW-FL"       // double 冷冻水总管流量
#define CCWS_T          "CCWS-T"        // double 冷却水总管供水温度
#define CCWR_T          "CCWR-T"        // double 冷却水总管回水温度
#define CCWS_P          "CCWS-P"        // double 冷冻水总管供水压力
#define CCWR_P          "CCWR-P"        // double 冷却水总管回水压力
#define CCW_FL          "CCW-FL"        // double 冷却水总管流量
#define WTR1_P          "WTR1-P"        // double 最不利末端压差测量点1
#define WTR2_P          "WTR2-P"        // double 最不利末端压差测量点2
#define WTR3_P          "CWTR3-PH"      // double 最不利末端压差测量点3
#define OA_T            "OA-T"          // double 室外温度
#define OA_H            "OA-H"          // double 室外湿度

#define SYS_FSM     (100)               // 系统状态机编号

struct single_point{
    pthread_mutex_t lock;

    point_prop_t pp;
    struct list_head clist;             // 用于链接开关的命令点位
    struct list_head slist;             // 用于链接开关的状态点位

    bool flag_c;    // clist 被操作过就置1, ‘被操作过’的链表依然可能为空
    bool flag_s;    // slist 被操作过就置1, ‘被操作过’的链表依然可能为空
};

/* 消息队列buf, 目前只用于事件的收发 */
typedef struct _cpo_msg_t{
	long    mtype;
    int     fsmevt; // 状态机事件
    int     fsmno;  // 状态机号， SYS_FSM: 表示系统状态机, 其他状态机号 = 冷机号, 不能用宏定义
	char    data[1024];
}cpo_msg_t;

/* 消息队列类型 */
typedef enum _cp_msg_tp{
	CPO_MQTP_EVENT = 1          // 消息队列的类型不能==0
}cp_msg_tp;

/* 通用子设备属性描述符 */
typedef struct _dev_prop_t{
    unsigned int vir_num;       // 虚点个数
    unsigned int real_num;      // 实点个数
    unsigned int points_num;    // 虚+实

    point_prop_t *points;       // 点位集合

    bool is_vsd;            // 是否是变频
    bool is_full_spd;       // 是否满频率运行，如果塔被关闭, 那么此变量设为!FULLSPEED
    double vsd_max;         // 频率上限
    double vsd_min;         // 频率下限

    bool is_run;            // 是否运行, 
                            // 不同设备的运行状态点位不一定配置，所以程序每enable一个设备，
                            // 要手动设置设个变量，同时也可以轮询每个设备的运行状态点位，然后更新此值

    unsigned int accl_rt;   // 累计运行时间(秒)
    unsigned int curr_rt;   // 本次运行时间(秒)
    unsigned int down_tm;   // 上次停机时间 gettimeofday()获取的秒
    unsigned int start_tm;  // 上次开机时间 gettimeofday()获取的秒

}dev_prop_t;

/* ========================================分隔线==================================== */

/* 水泵描述符，冷却水泵和冷冻水泵的描述符通用 */
typedef struct _pchwp_dev_t{
    dev_prop_t wp_prop;
    unsigned int sn;            // 水泵编号

    struct list_head list;
}wp_dev_t;

/* 冷却水泵 头 描述符 */
typedef struct _cwp_head_t{
    pthread_mutex_t lock;

    unsigned int cwp_num;       // 初级冷冻水泵个数
    unsigned int cwp_on_cnt;    // 初级冷冻水泵运行个数

    struct list_head list;
}cwp_head_t;

/* 初级冷冻水泵 头 描述符 */
typedef struct _pchwp_head_t{
    pthread_mutex_t lock;

    unsigned int pchwp_num;     // 初级冷冻水泵个数
    unsigned int pchwp_on_cnt;  // 初级冷冻水泵运行个数

    struct list_head list;
}pchwp_head_t;

/* ========================================分隔线==================================== */

/* 冷机描述符 */
typedef struct _ch_dev_t{
    dev_prop_t ch_prop;
    unsigned int sn;            // 冷机编号

    double ch_real_ip;          // 输入电功率，单位KW          -1: 无效
    double ch_max_op;           // 输出制冷功率，单位冷吨       -1: 无效

    struct list_head list;
}ch_dev_t;

/* 冷机 头 描述符 */
typedef struct _ch_head_t{
    pthread_mutex_t lock;

    unsigned int ch_num;        // 冷机个数
    unsigned int ch_on_cnt;     // 冷机运行个数

    int add_flag;               // 加机标志：true: 可加机
    unsigned int add_tm;        // add_flag == true 同时 tm>30min 才能加机 

    int sub_flag;               // 减机标志：true: 可减机
    unsigned int sub_tm;        // sub_flag == true 同时 tm>30min 才能减机 

    dev_prop_t chg_rp;          // 冷机组的实点位集
    struct list_head list;
}ch_head_t;

/* ========================================分隔线==================================== */

/* 冷却塔风扇描述符 */
typedef struct _ctf_dev_t{
    dev_prop_t ctf_prop;    // 风扇点位
    unsigned int sn;        // 风扇编号

    struct list_head list;
}ctf_dev_t;

/* 冷却塔描述符(暨冷却塔风扇头描述符) */
typedef struct _ct_dev_t{
    pthread_mutex_t lock;       // 注意，新增一个塔时，别忘了初始化本锁

    unsigned int ctf_num;       // 风扇个数
    unsigned int ctf_on_cnt;    // 风扇运行个数, 暂时不需要这个变量, 塔内风扇都是同时运行或停止

    dev_prop_t ct_prop;         // 冷却塔属性描述符

    unsigned int sn;            // 塔编号

    struct list_head list_ct;       // 作为节点, 接入ct_head_t的链表, 
    struct list_head list_ctf_hd;   // 作为塔内风扇的链表头, 用于链接ctf_dev_t *node
}ct_dev_t;

/* 冷却塔头 描述符 */
typedef struct _ct_head_t{
    pthread_mutex_t lock;

    unsigned int ct_num;    // 冷却塔个数
    unsigned int ct_on_cnt; // 冷却塔运行个数

    dev_prop_t ctg_rp;      // 塔组的实点位集，比如总蝶阀的开关，状态等点位

    struct list_head list;
}ct_head_t;

/* ========================================分隔线==================================== */

/* 冷源设备描述符 */
typedef struct _cpo_dev_t{
    pthread_mutex_t lock;

    char device_id[30];         // 设备唯一ID，将虚点的deviceKey作为当前设备总ID(历史原因)

    ct_head_t ct_head;          // 冷却塔头
    cwp_head_t cwp_head;        // 冷却水泵头
    pchwp_head_t pchwp_head;    // 初级冷冻水泵头
    ch_head_t ch_head;          // 冷机头

    dev_prop_t sys_rp;  // 系统实点位, 为了代码方便, 这里将所有的系统实点看作是一个设备, 从而使用通用的设备描述符(有些内部变量用不到)
    dev_prop_t sys_vp;  // 所有虚点位, 和sys_rp一样, 将虚点看作一个设备, 这样用一套代码处理即可.

    pthread_cond_t deltmr_cond;

    bool add_dev;       // 标志位：addDevice后设为true
}cpo_dev_t;

enum error_code read_sysvp_byname(char *name, data_type_u *val);
enum error_code read_sysrp_byname(char *name, data_type_u *val);

point_prop_t *is_point_exist(char *name, dev_prop_t *dev_prop);

void setval_2devdp_byname(char *name, dev_prop_t *dev_prop, data_type_u val, enum type_of_val tp);
void setval_2devdp_bypp(point_prop_t *pp, data_type_u val, enum type_of_val tp);

void sendpoint_2otherapp(point_prop_t *pp);

void add_sp_2slist(point_prop_t *pp, struct list_head *hd);
void add_sp_2clist(point_prop_t *pp, struct list_head *hd);

point_prop_t *find_point_bydf(char *dk, char *func);
point_prop_t *find_point_bynm(char *name);
point_prop_t *find_point_from_devdp_bynm(char *name, dev_prop_t *dev_prop);

void set_cmdpoint_ifexist(char *name, dev_prop_t *dev_prop, data_type_u val, enum type_of_val tp, struct list_head *hd);

void *cpo_updprop_thread(void *arg);
void sigroutine(int signo);

#endif  //__CPODATA_H__